import { getToken } from '@/utils/auth'
import {
  handleToken,
  handleLoading,
  Cache,
  handleRepeat,
  collectError,
  handleConnect,
  handleError
} from '.'

export const cache = new Cache()
/**
 * 请求之前的处理
 * @param {*} config axios request config
 * @param {*} _customConfig
 * @param {*} requestKey
 */
export const handleBeforeRequest = ({ config, _customConfig, requestKey }) => {
  const { isNeedToken, isNeedLoading, delay, loadingCallback } = _customConfig

  if (isNeedToken) {
    const token = getToken()
    handleToken(config, token)
  }

  if (isNeedLoading) {
    handleLoading({
      loading: true,
      requestKey,
      delay,
      loadingCallback
    })
  }
}

// 请求之后的处理 即 finally
export const handleAfterRequest = ({ _customConfig, requestKey }) => {
  const { isNeedLoading, loadingCallback, delay } = _customConfig

  if (isNeedLoading) {
    handleLoading({ loading: false, requestKey, delay, loadingCallback })
  }
}

// 请求成功处理 res -> 响应值
export const handleSuccessRequest = ({
  instance,
  config,
  _customConfig,
  requestKey,
  res
}) => {
  // 设置缓存
  if (_customConfig.isNeedCache) {
    cache.set(requestKey, res)
  }

  // 重置重连数
  handleConnect({
    instance,
    config,
    customConfig: _customConfig,
    requestKey,
    isDelete: true
  })

  return res
}

// 错误处理
export const handleErrorReuqest = async ({
  error,
  config,
  customConfig,
  _customConfig,
  instance,
  requestKey
}) => {
  const { response: { status = 0 } = {} } = error
  const { notPermissionCode, refreshToken, isNeedError, errorCallback } =
    _customConfig
  // 处理重复请求 (这里调用的原因： 因为 catch 比 finally 调用快)
  handleRepeat(requestKey, false)

  // 收集错误信息
  collectError(instance, error)

  // 错误状态码处理
  if (status !== notPermissionCode) {
    // 重连
    const connectResult = handleConnect({
      instance,
      config,
      customConfig: _customConfig,
      requestKey,
      isDelete: false
    })
    if (connectResult) return connectResult
  } else {
    // 重新刷新 token
    try {
      if (refreshToken && typeof refreshToken === 'function') {
        await _customConfig.refreshToken()
        // 重新发起之前 token 失效的请求
        return instance.request(config, customConfig)
      }
    } catch (error) {
      return Promise.reject(error)
    }
  }

  if (isNeedError) {
    handleError(error, errorCallback)
  }

  return Promise.reject(error)
}
